
from qtpy.QtGui import QStandardItemModel, QStandardItem
from lxml.etree import HTMLParser, HTML



class HtmlItem(QStandardItem):
    def __init__(self, tag, attrib, parent: QStandardItem):
        super().__init__()
        self.tag = tag
        self.attrib = attrib
        self.setText(self.tag)
        self.tdata = ''
        self.comment = ''
        parent.appendRow(self)


class Target:

    def __init__(self, root):
        self.root = root
        self.pipe = [self.root]
        self.item = None
        self.close_tag = ''

    def start(self, tag, attrib):
        self.item = HtmlItem(tag, attrib, self.pipe[-1])
        self.pipe.append(self.item)
        # print("start %s %r" % (tag, dict(attrib)))

    def end(self, tag):
        # print("end %s" % tag)
        self.close_tag = tag
        self.pipe.pop(len(self.pipe) - 1)

    def data(self, data):
        if self.item is not None:
            self.item.tdata += data
        # print("data %r" % data)

    def comment(self, text):
        if self.item is not None:
            self.item.comment = text
        # print("comment %s" % text)

    def close(self):
        # print("close")
        return self.close_tag


class HtmlDomModel(QStandardItemModel):

    def __init__(self, html_context: str, parent=None):
        super().__init__(parent)
        self.setColumnCount(1)
        self.setHorizontalHeaderItem(0, QStandardItem('tags'))
        self.root: QStandardItem = self.invisibleRootItem()
        self.htmlstr = html_context
        self.et = None
        self.init_model()

    def init_model(self):
        try:
            if self.htmlstr:
                parser = HTMLParser(target=Target(self.root))
                self.et = HTML(self.htmlstr, parser=parser)
            
        except Exception as e:
            print(type(e), e)
            return

    def get_item_xpath(self, item: HtmlItem):
        if item is None:
            return ''
        tp = []
        while item.text() != '':
            tp.append(item.text())
            item = item.parent()
            if item is None:
                break
        tp.append('/')
        tp.reverse()
        return '/'.join(tp)


class ScraperItemModel(QStandardItemModel):

    def __init__(self, rows: int =0, columns: int = 3, parent=None):
        super(ScraperItemModel, self).__init__(rows, columns, parent)
        self.setHorizontalHeaderLabels(['name', 'type', 'search_rule'])

    def add_row(self, name: str, type_: str, search_rule: str):
        self.appendRow(
            [QStandardItem(str(name)), QStandardItem(str(type_)), QStandardItem(str(search_rule))])

    def get_data(self):
        data = []
        for row in range(self.rowCount()):
            data.append([self.item(row, col).text() for col in range(self.columnCount())])
        return data

